Q: How can I add message queue asynchronous
timer interrupts to my program?
Normal programs, and especially GUI programs, are synchronized by the message queue. When
a message is processed by XgrProcessMessages() , all actions caused by processing the
message are performed in the expected order before the next message is processed. Programs
can therefore assume that program variables will not be unexpectedly modified during
message processing. This reduces the complexity of programs enormously.
Most programs with asynchronous aspects simulate asynchronous behavior by setting and
starting GraphicsDesigner grid timers which add TimeOut messages to the message queue when
they expire. When these TimeOut messages are subsequently processed by
XgrProcessMessages() , a grid function receives the TimeOut message and can process the
asynchronous timer event in the normal straightforward manner because the asynchronous
timer has been synchronized by its passage through the message queue.
Programs with asynchronous aspects that cannot be simulated by timers often employ a
similar technique. One line is added to the message processing loop in their Entry()
function to call a function that performs asynchronous activity. Again, apparently
asynchronous activity is processed in a synchronous manner.
DO
XgrProcessMessages (0)
Asynchronous () ' check/process asynchronous program aspects
LOOP
Though there are many other methods to handle asynchronous activity in a synchronous way,
some programs require some true asynchronous processing. Consider a program that needs to
respond to certain conditions within a limited period of time, but also contains one or
more functions that may take longer to complete than the response interval. The
synchronous way to handle this situation is to add a line that calls an asynchronous
processing function in as many places as necessary to assure adequate response time. The
shorter the response interval gets, however, the more places the asynchronous processing
function must be called. Furthermore, the length of time required to execute various parts
of a program depends on computer speed, and is therefore not portable unless written for
the slowest possible machine.
The standard function library contains two functions that support fully asynchronous
processing, namely XstStartTimer() and XstKillTimer() . Timers created by XstStartTimer()
are not associated with GraphicsDesigner or the message queue. When they expire, the
function associated with the timer is called immediately, potentially between ANY two
machine instructions. Program variables can thus be in any state, and its even possible
for these timers to interrupt programs between machine instructions that update the two
32-bit parts of GIANT and DOUBLE variables! Therefore the program must be written to
anticipate all possible adverse interactions and avoid them. As long as asynchronous
processing functions are not themselves interrupted and do not read variables that are
altered elsewhere in the program, they can be fairly simple. Otherwise careful and
detailed design of handshaking is required to avoid disasterous interaction between the
normal and asynchronous parts of programs.